<?php

namespace App\Service\ChatGroup;

use App\Enums\WorkOrder\MissionEnum;
use App\Enums\WorkOrder\OrderEnum;
use App\Library\Lock\NxLock;
use App\Library\Rms\RmsShopApi;
use App\Library\Rms\RmsUserApi;
use App\Models\Appraise\AppraiseModel;
use App\Models\ChatGroup\ChatGroupFAQModel;
use App\Models\ChatGroup\ChatGroupModel;
use App\Models\ChatGroup\ChatGroupUserModel;
use App\Models\Common\ConfigModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopAddressModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationRegionMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\WorkOrder\WorkOrderApplyMainModel;
use App\Service\BaseService;
use Illuminate\Database\Eloquent\HigherOrderBuilderProxy;
use Illuminate\Support\Facades\DB;

class ChatGroupService extends BaseService
{
    /**
     * 初始化群组
     * @param int $shopId
     * @param int $type
     * @param bool $isScript
     */
    public static function initGroup(int $shopId, int $type, $isScript = false)
    {
        // 创建群聊
        $group = ChatGroupModel::query()
                               ->where('shopId', $shopId)
                               ->where('type', $type)
                               ->first();

        if ($group && !$isScript) {
            return $group;
        }

        switch ($type) {
            case ChatGroupModel::TYPE_CUSTOMER_SERVE:
                $name = '专属服务群';
                break;
            default:
                self::throwErr('不存在的群聊类型');
        }

        $closureDo = function () use ($shopId, $type, $name, $group) {

            DB::beginTransaction();

            if (!$group) {
                // 创建群
                $group = ChatGroupModel::query()->create(['shopId' => $shopId, 'name' => $name, 'type' => $type]);
            }

            // 拉人进群
            self::initGroupUser($shopId, $group->id);

            DB::commit();

            return $group;
        };

        $closureReTry = function () use ($shopId, $type, $isScript) {
            return self::initGroup($shopId, $type, $isScript);
        };

        return (new NxLock())->nx($closureDo, $closureReTry,
            NxLock::generateLockKey(__CLASS__ . '_' . __FUNCTION__, ...[$shopId, $type]));
    }

    /**
     * 初始化群组的用户
     * @param int $shopId
     * @param int $groupId
     * @return void
     */
    public static function initGroupUser(int $shopId, int $groupId): void
    {
        // 生成群聊初始用户
        $users = self::generateUsers($shopId);

        // 当前关联的所有人
        $groupUsers = ChatGroupUserModel::query()->where('groupId', $groupId)->get()->map(function ($item) {
            return $item->userId . '-' . $item->role;
        })->toArray();

        // 过滤已经存在的人员
        $insertArr = collect($users)->map(function ($item) use ($groupId, $shopId, $groupUsers) {
            if (in_array($item['userId'] . '-' . $item['role'], $groupUsers)) {
                return null;
            }

            return [
                'groupId'   => $groupId,
                'shopId'    => $shopId,
                'userId'    => $item['userId'],
                'role'      => $item['role'],
                'alias'     => $item['alias'],
                'avatar'    => $item['avatar'],
                'tag'       => $item['tag'],
                'createdAt' => time(),
                'updatedAt' => time(),
            ];
        })->filter()->values()->toArray();

        if ($insertArr) {
            ChatGroupUserModel::query()->insert($insertArr);
        }
    }

    /**
     * 生成群聊初始用户
     * @param int $shopId
     * @return array
     */
    public static function generateUsers(int $shopId): array
    {
        $users = [];

        // 老板
        $mainProcessId  = OpenShopMainProcessModel::getIdByShopId($shopId);
        $signOrder      = OpenShopSignOrderModel::query()
                                                ->where('mainProcessId', $mainProcessId)
                                                ->orderByDesc('id')
                                                ->select('merchantUserId', 'orderNo')->first();
        $merchantUserId = $signOrder->merchantUserId ?? 0;
        $orderNo        = $signOrder->orderNo ?? '';

        if ($merchantUserId) {
            $users[] = [
                'userId' => $merchantUserId,
                'role'   => ChatGroupUserModel::ROLE_BOSS,
                'alias'  => '',
                'avatar' => '',
                'tag'    => 0,
            ];
        }

        // 获得门店下所有员工-只限商家APP的账户 如pos权限的人员无法登录app
        $staffList = (new RmsShopApi())->getShopStaffListByShopId($shopId, false, false, RmsShopApi::ROLE_BUSINESS_TYPE)['data']['list'] ?? [];
        if ($staffList) {
            collect($staffList)->map(
                function ($staff) use (&$users) {
                    $users[] = [
                        'userId' => $staff['id'],
                        'role'   => ChatGroupUserModel::ROLE_EMPLOYEE,
                        'alias'  => '',
                        'avatar' => '',
                        'tag'    => 0,
                    ];
                }
            );
        }

        // 获取总部人员配置
        $config = json_decode(ConfigModel::getValue('chatGroup', 'chatGroupUserCustomerServeConfig'), true);
        if (!$config) {
            return $users;
        }

        // 固定人员
        foreach ($config['customerServe'] as $val) {
            $users[] = [
                'userId' => $val['userId'],
                'role'   => ChatGroupUserModel::ROLE_KF,
                'alias'  => $val['alias'],
                'avatar' => $val['avatar'],
                'tag'    => $val['tag'],
            ];
        }

        // 实施
        // 判断门店属于哪个组织架构
        $provinceCode = OpenShopAddressModel::getData($orderNo)->provinceCode ?? 0;
        if (!$provinceCode) {
            return $users;
        }
        $manageId = (int)OpenShopOrganizationRegionMappingModel::query()
                                                               ->where('provinceCode', $provinceCode)
                                                               ->value('manageId');
        if (!$manageId) {
            return $users;
        }

        $implementFlag = false;
        $otherImp      = [];
        foreach ($config['implement'] as $val) {
            if (in_array($manageId, $val['manageIds'])) {
                $users[]       = [
                    'userId' => $val['userId'],
                    'role'   => ChatGroupUserModel::ROLE_KF,
                    'alias'  => $val['alias'],
                    'avatar' => $val['avatar'],
                    'tag'    => $val['tag'],
                ];
                $implementFlag = true;
            }

            if ($val['manageIds'] == [999]) {
                $otherImp = $val;
            }
        }

        // 取999的实施
        if (!$implementFlag) {
            $users[] = [
                'userId' => $otherImp['userId'],
                'role'   => ChatGroupUserModel::ROLE_KF,
                'alias'  => $otherImp['alias'],
                'avatar' => $val['avatar'],
                'tag'    => $val['tag'],
            ];
        }

        return $users;
    }


    /**
     * 历史统计
     * @param $shopId
     * @return array
     */
    public static function historyStatistics($shopId): array
    {
        // 获取工单总数和未完成工单数
        $workOrderCounts = WorkOrderApplyMainModel::query()
            ->where('step', '>', MissionEnum::STEP_1)
            ->selectRaw('COUNT(*) AS totalCount, SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) AS unfinishedCount', [OrderEnum::MAIN_STATUS_ING])
            ->where('shopId', $shopId)
            ->first();

        $workOrderTotalCount      = $workOrderCounts->totalCount;
        $workOrderUnfinishedCount = $workOrderCounts->unfinishedCount;

        // 获得评价反馈的总数和未完成数
        $appraiseCounts = AppraiseModel::query()
            ->selectRaw('COUNT(*) AS totalCount, SUM(CASE WHEN status in (?, ?) THEN 1 ELSE 0 END) AS unfinishedCount', [AppraiseModel::STATUS_DEFAULT, AppraiseModel::STATUS_DEAL_ING])
            ->where('shopId', $shopId)
            ->first();

        $appraiseCountsTotalCount      = $appraiseCounts->totalCount;
        $appraiseCountsUnfinishedCount = $appraiseCounts->unfinishedCount;

        return [
            'shopId'                        => $shopId,
            'shopName'                      => (new RmsShopApi())->getShopByIds([$shopId], ['name'])['data']['shopList'][0]['name'] ?? $shopId,
            'workOrderTotalCount'           => (int)$workOrderTotalCount,
            'workOrderUnfinishedCount'      => (int)$workOrderUnfinishedCount,
            'appraiseCountsTotalCount'      => (int)$appraiseCountsTotalCount,
            'appraiseCountsUnfinishedCount' => (int)$appraiseCountsUnfinishedCount,
        ];
    }


    /**
     * 发送工单链接配置
     * @return array
     */
    public static function workOrderSendUrl(): array
    {
        return ChatGroupFAQModel::getSendWorkOrder();
    }

    /**
     * 群聊内测店铺
     * @return HigherOrderBuilderProxy|mixed|string|null
     */
    public static function betaShopIds()
    {
        return ConfigModel::getValueNewJson('chatGroup', 'betaShopIds');
    }

}
